package com.bwie.service.impl;

import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bwie.pojo.TLog;
import com.bwie.pojo.TProd;
import com.bwie.pojo.TbMenu;
import com.bwie.pojo.TbUser;
import com.bwie.service.TbUserService;
import com.bwie.mapper.TbUserMapper;
import com.bwie.state.CheckEnum;
import com.bwie.utils.MobileMessageUtil;
import com.bwie.utils.R;
import com.bwie.vo.AdminLoginVo;
import com.bwie.vo.PageInfoVo;
import com.github.tobato.fastdfs.domain.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import jdk.nashorn.internal.parser.Token;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.Acknowledgment;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
* @author Yoo19
* @description 针对表【tb_user(用户表)】的数据库操作Service实现
* @createDate 2025-04-21 18:42:38
*/
@Service
public class TbUserServiceImpl extends ServiceImpl<TbUserMapper, TbUser>
    implements TbUserService{

    @Autowired
    private TbUserMapper tbUserMapper;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    HttpServletRequest request;
    @Autowired
    FastFileStorageClient fastFileStorageClient;
    @Autowired
    KafkaTemplate kafkaTemplate;
    @Autowired
    JavaMailSender javaMailSender;

    @Override
    public R getUserById(Integer id) {
        TbUser tbUser = tbUserMapper.selectById(id);
        if(tbUser == null){
            return R.ERROR(404,"用户不存在");
        }

        tbUser.setUserPass(null);

        return R.OK(tbUser);
    }

    @Override
    public R adminLogin(AdminLoginVo adminLoginVo) {
        //--只要登录了就要记录日志
        TLog tLog = new TLog();
        tLog.setCreateTime(new Date());
        tLog.setLogName("登录");
        tLog.setIp(request.getRemoteAddr());
        tLog.setLogType(1);

        String message="";


        //获取用户信息
        TbUser tbUser = tbUserMapper.selectOne(new QueryWrapper<TbUser>().lambda().eq(TbUser::getUserName, adminLoginVo.getUserName()));
        if (tbUser == null) {
            message="用户不存在：登录账号("+adminLoginVo.getUserName()+")登录密码("+adminLoginVo.getUserPass();
            tLog.setLogContent(message);
            kafkaTemplate.send("topic-log",JSON.toJSONString(tLog));
            return R.ERROR(404, "用户不存在");
        }
        //校验密码
        if (!tbUser.getUserPass().equals(adminLoginVo.getUserPass())) {
            message="密码错误：登录账号("+adminLoginVo.getUserName()+")登录密码("+adminLoginVo.getUserPass();
            tLog.setLogContent(message);
            kafkaTemplate.send("topic-log",JSON.toJSONString(tLog));
            return R.ERROR(404, "密码错误");
        }
        //生成token
        String token = Jwts.builder().signWith(SignatureAlgorithm.HS256, "123456")
                        .claim("userId", tbUser.getUserId())
                        .claim("nickName",tbUser.getNickName())
                        .compact();
        //缓存token
        String redisKey="token-" + tbUser.getUserId();
        redisTemplate.opsForValue().set(redisKey, token, 60, TimeUnit.MINUTES);


        //返回token
        tbUser.setToken(token);
        tbUser.setUserPass(null);

        //登录成功
        message="登录成功：登录账号("+adminLoginVo.getUserName()+")登录密码("+adminLoginVo.getUserPass();
        tLog.setLogContent(message);
        kafkaTemplate.send("topic-log",JSON.toJSONString(tLog));

        return R.OK(tbUser);
    }

    @Override
    public R getUserList(PageInfoVo pageInfoVo) {

        Page<TbUser> page = new Page<>(pageInfoVo.getPageNum(), pageInfoVo.getPageSize());

        LambdaQueryWrapper<TbUser> wrapper = new LambdaQueryWrapper<>();
        if(StringUtils.isNotEmpty(pageInfoVo.getKeyWord())){
            wrapper.like(TbUser::getUserName,pageInfoVo.getKeyWord())
                    .or()
                    .like(TbUser::getNickName,pageInfoVo.getKeyWord())
                    .or()
                    .like(TbUser::getUserMobile,pageInfoVo.getKeyWord())
                    .or()
                    .like(TbUser::getUserEmail,pageInfoVo.getKeyWord());
        }



        wrapper.orderByDesc(TbUser::getUserId);
        Page<TbUser> tbUserPage = tbUserMapper.selectPage(page,
                wrapper);




        return R.OK(tbUserPage);
    }

    @Override
    public R register(TbUser tbUser) {
//        唯一性校验
        TbUser one = tbUserMapper.selectOne(new LambdaQueryWrapper<TbUser>().eq(TbUser::getUserName, tbUser.getUserName()));

        if(one != null){
            return R.ERROR(500,"用户名重复");
        }
//        添加
        tbUser.setCreateTime(new Date());
        tbUserMapper.insert(tbUser);
        return R.OK();
    }

    @Override
    public R checkUser(TbUser tbUser) {
        //判断用户是否存在
        TbUser user = tbUserMapper.selectById(tbUser.getUserId());
        if(user==null){
            return R.ERROR(500,"用户不存在");
        }
        //如果审核驳回必须填写审核理由
        if(tbUser.getUserStatus().equals(CheckEnum.CHECK_NO.getCode())){
            //审核驳回判断审核理由
            if(StringUtils.isEmpty(tbUser.getReason())){
                return R.ERROR(500,"审核驳回必须填写审核理由");
            }
        }
        //审核
        user.setUserStatus(tbUser.getUserStatus());
        user.setReason(tbUser.getReason());

        tbUserMapper.updateById(user);

        //发送异步通知  成功发送手机短信，失败发送邮件
        kafkaTemplate.send("topic-user", JSON.toJSONString(user));
        System.out.println("消息发送："+JSON.toJSONString(user));

        return R.OK();
    }

    @KafkaListener(topics = "topic-user")
    public void RevUserMessage(String msg, Acknowledgment acknowledgment){
        System.out.println("接收消息："+msg);

        TbUser tbUser = JSON.parseObject(msg, TbUser.class);
        if(tbUser.getUserStatus().equals(CheckEnum.CHECK_OK.getCode())){
//            审核通过
            String phone = tbUser.getUserMobile();
            String content = "恭喜您,您的账号审核已通过,请登录系统";
            MobileMessageUtil.sendMobileMessage(phone,content);
            System.out.println("发送短信到："+phone+"消息为："+content);

        }else if(tbUser.getUserStatus().equals(CheckEnum.CHECK_NO.getCode())){
            try {
                MimeMessage mimeMessage = javaMailSender.createMimeMessage();
                MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true);
                messageHelper.setFrom("1951160365@qq.com");
                messageHelper.setTo(tbUser.getUserEmail());
                messageHelper.setSubject("用户审核驳回结果");
                messageHelper.setText("您的账户审核被驳回,请重新注册");
                javaMailSender.send(mimeMessage);

                System.out.println("邮件发送成功");
            } catch (MessagingException e) {
                e.printStackTrace();

            }

        }

        acknowledgment.acknowledge();
    }

    @Override
    public R getMyInfo() {

        String token = request.getHeader("token");
        if(token==null){
            return R.ERROR(500,"请先登录");
        }
        Claims claims = Jwts.parser().setSigningKey("123456").parseClaimsJws(token).getBody();
        Integer userId = claims.get("userId", Integer.class);

        TbUser tbUser = tbUserMapper.selectById(userId);

        return R.OK(tbUser);
    }

    @Override
    public R updateUser(TbUser tbUser) {
        TbUser tbUser1 = tbUserMapper.selectById(tbUser.getUserId());
        if(tbUser1 == null ){
            return R.ERROR(404,"用户不存在");
        }

        tbUserMapper.updateById(tbUser);
        return R.OK();
    }

    @Override
    public R uploadFile(MultipartFile file) {

        try {
            String extName = FileNameUtil.extName(file.getOriginalFilename());
            StorePath storePath = fastFileStorageClient.uploadFile(file.getInputStream(), file.getSize(), extName, null);
            String url = "http://192.168.80.192:8888/" + storePath.getFullPath();
            return R.OK(url);
        } catch (IOException e) {
//            throw new RuntimeException(e);
            e.printStackTrace();
            return R.ERROR(500,"上传失败");
        }
    }

    @Override
    public R deleteUser(Integer userId) {
        TbUser tbUser = tbUserMapper.selectById(userId);
        if(tbUser == null){
            return R.ERROR(404,"用户不存在");
        }

        tbUserMapper.deleteById(userId);
        return R.OK();
    }

    @Override
    public R deleteUserBatch(List<TbUser> userList) {
        for (TbUser tbUser : userList) {
            tbUserMapper.deleteById(tbUser.getUserId());
        }
        return R.OK();
    }

    @Override
    public R getMyRoleList() {
        String token = request.getHeader("token");
        if(token == null){
            return R.ERROR(500,"请先登录");
        }

        Claims claims = Jwts.parser().setSigningKey("123456").parseClaimsJws(token).getBody();
        Integer userId = claims.get("userId", Integer.class);

        List<String> userRoleList = tbUserMapper.getUserRoleList(userId);
        return R.OK(userRoleList);
    }

    @Override
    public R getUserMenuTree() {

        String token = request.getHeader("token");
        if(token == null){
            return R.ERROR(500,"请先登录");
        }

        Claims claims = Jwts.parser().setSigningKey("123456").parseClaimsJws(token).getBody();
        Integer userId = claims.get("userId", Integer.class);

        List<TbMenu> menuList = tbUserMapper.getUserMenuTree(userId);

        List<Tree<String>> treeList = TreeUtil.build(menuList, "0", (menu, treeNode) -> {
            treeNode.setId("" + menu.getMenuId());
            treeNode.setName(menu.getMenuName());
            treeNode.setParentId("" + menu.getMenuPid());
            treeNode.putExtra("path", menu.getMenuPath());
        });


        return R.OK(treeList);
    }

    @KafkaListener(topics = "topic-prod")
    public void RevProdMessage(String msg,Acknowledgment acknowledgment){
        System.out.println("接受消息：" + msg);
        TProd tProd = JSON.parseObject(msg, TProd.class);
        if(tProd.getProdStatus() == 2){
            //商品通过发送短信
            TbUser tbUser = tbUserMapper.selectById(tProd.getUserId());
            String mobile = tbUser.getUserMobile();
            String content = "恭喜您，您的商品审核通过请登录,系统查看";
            MobileMessageUtil.sendMobileMessage(mobile,content);
        }else if(tProd.getProdStatus() == 3){
            //商品未通过发送邮件
            try {
                TbUser tbUser = tbUserMapper.selectById(tProd.getUserId());
                String email = tbUser.getUserEmail();
                MimeMessage mimeMessage = javaMailSender.createMimeMessage();
                MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage);
                messageHelper.setFrom("1951160365@qq.com");
                messageHelper.setTo(tbUser.getUserEmail());
                messageHelper.setSubject("商品驳回通知");
                messageHelper.setText("抱歉,您的商品"+tProd.getProdName()+"被驳回,请重新上传");

                javaMailSender.send(mimeMessage);
            } catch (MessagingException e) {
                e.printStackTrace();
            }
        }

        acknowledgment.acknowledge();
    }
}




